openUBMC pre-commit 代码风格可视化 - 详细设计说明书
| 所属SIG组: | CICD |
| 落入版本: | 26.09 |
| 设计人员: | 马思雨 |
| 日期: | 2026.7.16 |
Copyright © 2026 openUBMC Community
您对"本文档"的复制,使用,修改及分发受木兰宽松许可证, 第2版协议(以下简称"MulanPSL2")的约束。 为了方便用户理解,您可以通过访问https://license.coscl.org.cn/MulanPSL2了解MulanPSL2的概要 (但不是替代)。 MulanPSL2的完整协议内容您可以访问如下网址获取:https://license.coscl.org.cn/MulanPSL2。
改版记录
| 日期 | 修订版本 | 修订描述 | 作者 | 审核 |
|---|---|---|---|---|
| 2026/07/16 | 0.0.1 | 初始版本 | masiyu |
List of abbreviations 缩略语清单 :
| Abbreviations 缩略语 | Full spelling 英文全名 | Chinese explanation 中文解释 |
|---|---|---|
| pre-commit | pre-commit framework | Git钩子管理框架 |
| clang-format | ClangFormat | C/C++代码格式化工具 |
| ruff | Ruff | Python极速lint+format工具 |
| Prettier | Prettier | 多语言代码格式化工具 |
| StyLua | StyLua | Lua代码格式化工具 |
| Luacheck | Luacheck | Lua静态分析(lint)工具 |
| CSR | Component Self-description Record | 组件自描述记录 |
| PSR | Product Self-description Record | 产品自描述记录 |
[TOC]
1.功能分析
1.1 功能背景
原有代码规范性检查依赖流水线codecheck门禁,仅在代码提交到远端后触发,开发者无法在本地及时识别和清理问题,导致反复提交-修复循环;各语言栈(C/C++、Python、JS/Vue、Lua)原本均无pre-commit钩子,既无格式化也无lint;编码规范未以配置文件形式固化到仓库,风格不可见。
引入pre-commit机制后的价值:
- 本地识别与清理:问题在git commit阶段即被发现和修复,无需等待远端流水线
- 代码一致性与规范性:确保社区所有开发者的代码风格保持一致
- 消减codecheck门禁:pre-commit覆盖原有codecheck大部分检查项,前置到本地提交阶段,提升合入效率
- 编码风格可视化:风格配置文件固化到各仓库,开发者直观可读
1.2 功能描述
- 引入pre-commit机制消减流水线codecheck门禁,判断代码仓是否存在
.pre-commit-config.yaml文件来确定是否开启 - openUBMC/pre-commit-hooks仓库(https://gitcode.com/openUBMC/pre-commit-hooks.git)提供统一钩子manifest
- 按语言栈分类提供钩子:C/C++(clang-format)、Python(ruff)、JS/Vue(prettier)、Lua(stylua-format + luacheck)
- 各组件仓库通过
.pre-commit-config.yaml按需引用,编码风格通过配置文件可视化(.clang-format/pyproject.toml/.prettierrc.js/.stylua.toml/.luacheckrc)
1.3 功能场景
| 场景编号 | 场景名称 | 描述 | 使用对象 |
|---|---|---|---|
| SC-01 | C/C++组件提交检查 | clang-format | C/C++开发者 |
| SC-02 | Python仓库提交检查 | ruff | Python开发者 |
| SC-03 | JS/Vue仓库提交检查 | prettier | WebUI开发者 |
| SC-04 | Lua组件提交检查 | stylua-format + luacheck | Lua开发者 |
| SC-05 | commit-msg校验 | conventional-commit + add-signoff-and-change-id | 所有开发者 |
| SC-06 | pre-commit机制启用判断 | 流水线通过.pre-commit-config.yaml判断是否开启 | CI/CD系统 |
开发者操作指导
判断是否开启pre-commit机制:查看代码仓是否存在.pre-commit-config.yaml文件。
操作步骤:
- 同步最新代码
- 安装pre-commit(参考仓库根目录CONTRIBUTING.md):bash
pip install pre-commit pre-commit install --hook-type commit-msg pre-commit install - 检查代码质量:bash
pre-commit run --all-files pre-commit run --hook-stage commit-msg --commit-msg-filename .git/COMMIT_EDITMSG
1.4 功能列表
| 功能编号 | 功能标题 | 功能描述 |
|---|---|---|
| F-01 | pre-commit机制引入 | 消减codecheck门禁,通过.pre-commit-config.yaml标识启用状态 |
| F-02 | clang-format钩子 | C/C++代码格式化(-style=file,读取.clang-format) |
| F-03 | ruff钩子 | Python格式化与lint(读取pyproject.toml) |
| F-04 | prettier钩子 | JS/Vue代码格式化(读取.prettierrc.js) |
| F-05 | stylua-format/luacheck钩子 | Lua格式化(.stylua.toml)与lint(.luacheckrc) |
| F-06 | conventional-commit钩子 | commit-msg格式校验 |
| F-07 | add-signoff-and-change-id钩子 | 自动追加Signed-off-by和Change-Id |
| F-08 | check-sr钩子 | .sr文件语法校验 |
2.功能设计
2.1 总体方案分析
2.1.1 方案详细设计
2.1.1.1 方案概述
| 关键点 | 描述 | 技术实现 |
|---|---|---|
| pre-commit机制引入 | 替代流水线codecheck门禁 | .pre-commit-config.yaml标识启用状态 |
| 统一钩子manifest | 单一仓库提供所有语言栈钩子定义 | .pre-commit-hooks.yaml |
| 按需引用 | 各仓库按语言栈选择性启用 | .pre-commit-config.yaml |
| 编码风格可视化 | 风格配置文件随仓库分发 | .clang-format/.prettierrc.js/.stylua.toml/.luacheckrc/pyproject.toml |
| codecheck门禁消减 | pre-commit覆盖的检查项消减流水线codecheck | 流水线判断.pre-commit-config.yaml |
2.1.1.2 开发视图
openUBMC/pre-commit-hooks仓库结构
openUBMC/pre-commit-hooks/
├── .pre-commit-hooks.yaml # 钩子manifest
├── .pre-commit-config.yaml # 推荐配置示例
├── hooks/ # openUBMC专属钩子(零网络依赖)
│ ├── conventional_commit.py
│ ├── add_signoff_and_change_id.py
│ └── check_sr.py
├── pyproject.toml # Python项目元数据
├── package.json # Node项目元数据
├── tests/ # 钩子单元测试
└── README.md组件仓库配置结构(按语言栈分类)
# C/C++ 组件(libmcpp)
├── .pre-commit-config.yaml # clang-format + 专属钩子
├── .clang-format # 格式化规则
# Python 组件(bingo)
├── .pre-commit-config.yaml # ruff + 专属钩子
├── pyproject.toml # ruff配置
# JS/Vue 组件(webui)
├── .pre-commit-config.yaml # prettier + 专属钩子
├── .prettierrc.js # 格式化规则
# Lua 组件(general_hardware)
├── .pre-commit-config.yaml # stylua-format + luacheck + 专属钩子
├── .stylua.toml # 格式化规则
├── .luacheckrc # lint规则2.1.1.3 运行视图
┌────────────┐ ┌──────────────────────┐ ┌─────────────────────────────────┐
│ git commit│────▶│ .pre-commit- │────▶│ 按语言栈筛选暂存文件 │
│ │ │ config.yaml │ │ .c/.cpp ──▶ clang-format │
└────────────┘ │ 声明 repo/rev/ │ │ .py ──▶ ruff │
│ hook ID │ │ .js/.vue──▶ prettier │
│ pre-commit 据此从 │ │ .lua ──▶ stylua/luacheck │
│ 远端仓库拉取钩子定义 │ └─────────────────────────────────┘
└──────────────────────┘ │
┌─────────────────────────────────────────┴─────────────────────┐
│ 钩子执行阶段 │
│ │
│ commit-msg 阶段: │
│ conventional-commit ──▶ 校验格式 │
│ add-signoff-and-change-id ──▶ 追加 trailer │
│ │
│ pre-commit 阶段(按文件类型): │
│ │
│ 语言栈 格式化(auto-fix) lint(检出阻断) │
│ ──────── ────────────── ────────────── │
│ C/C++ clang-format — │
│ Python ruff(format) ruff(check) │
│ JS/Vue prettier — │
│ Lua stylua-format luacheck │
│ │
└────────────────────────────────────────────────────────────────┘
│
┌──────────────────┴──────────────────┐
│ 结果判定 │
│ auto-fix 钩子 ──▶ 原地修改,重新提交 │
│ lint 错误 ──▶ 阻断提交,报错退出│
└──────────────────────────────────────┘2.1.2 依赖分析
| 外部依赖 | 类型 | 版本要求 | 用途 |
|---|---|---|---|
| pre-commit | Python工具 | >= 3.0.0 | 钩子管理框架 |
| clang-format | pip包 | 22.1.5 | C/C++格式化 |
| ruff | pip包 | 待定 | Python格式化+lint |
| prettier | npm包 | 3.0.3 | JS/Vue格式化 |
| stylua | 系统工具 | 最新 | Lua格式化(宿主机预装) |
| luacheck | 系统工具 | 最新 | Lua lint(宿主机预装) |
| Python | 运行环境 | >= 3.9 | 专属钩子运行 |
| Node.js | 运行环境 | >= 16 | prettier运行 |
2.1.3 北向接口分析
本功能为开发工具基础设施,不对外暴露北向接口。流水线通过判断.pre-commit-config.yaml是否存在确定是否开启pre-commit,开启后消减codecheck门禁。
2.1.4 兼容性分析
- 各钩子通过
.pre-commit-config.yaml选择性启用,未引用的仓库不受影响 - pre-commit前置了codecheck大部分检查项,消减后提升合入效率
- 判断是否开启:代码仓存在
.pre-commit-config.yaml即开启
2.1.5 定制化接口分析
| 钩子ID | 默认参数 | 配置文件 |
|---|---|---|
| clang-format | -i -style=file | .clang-format |
| ruff | — | pyproject.toml |
| prettier | --write | .prettierrc.js |
| stylua-format | --config-path .stylua.toml --verify | .stylua.toml |
| luacheck | --config .luacheckrc --codes --no-color --ranges | .luacheckrc |
2.1.6 ~ 2.1.9
不涉及配置导入导出、传感器新增、告警事件新增、系统锁定。
2.1.10 用例场景分析
| 用例编号 | 用例名称 | 前置条件 | 操作步骤 | 预期结果 |
|---|---|---|---|---|
| UC-01 | C/C++提交检查 | libmcpp已配置clang-format | 1. 修改.cpp 2. git commit | format auto-fix通过或阻断 |
| UC-02 | Python提交检查 | 仓库已配置ruff | 1. 修改.py 2. git commit | ruff格式化+lint通过 |
| UC-03 | JS/Vue提交检查 | webui已配置prettier | 1. 修改.vue 2. git commit | prettier格式化通过 |
| UC-04 | Lua提交检查 | general_hardware已配置stylua/luacheck | 1. 修改.lua 2. git commit | stylua格式化 + luacheck通过 |
| UC-05 | pre-commit启用 | 代码仓含.pre-commit-config.yaml | 1. pip install + pre-commit install | 钩子自动生效 |
| UC-06 | codecheck门禁消减 | 代码仓已开启pre-commit | 1. 提交代码 2. 流水线判断配置文件存在 | 消减codecheck,合入效率提升 |
2.2 非功能质量属性设计
2.2.1 扩展性分析
- 各格式化工具通过配置文件定制,仓库可差异化
- manifest可新增更多语言栈钩子(如Go/Rust)
- hooks/目录可新增openUBMC专属脚本
2.2.2 重用性分析
manifest和专属钩子被所有社区仓库复用,风格配置文件模式可被新仓库直接拷贝复用。
2.2.3 可测试性分析
- 社区流水线配置pre-commit门禁扫描修改内容
pre-commit run --all-files全量扫描
2.2.4 资料分析
README.md提供快速开始、钩子详解、配置定制和团队协作指南。组件仓库的CONTRIBUTING.md提供安装步骤。无对外API。
2.2.5 可靠性分析
- add-signoff-and-change-id和clang-format幂等
- lint错误阻断提交但不修改文件;auto-fix原地修改但git可回退
- clang-format缺失.clang-format时按LLVM默认风格(不报错)
- pre-commit覆盖的检查项可安全消减codecheck,未覆盖的仍保留在流水线
3.功能实现
3.1 功能实现设计
钩子定义示例
以已合入的clang-format为例,说明manifest中钩子的定义方式:
- id: clang-format
name: clang-format
description: C/C++ 代码格式化 (原地修改,使用项目 .clang-format)
entry: clang-format
language: python
types_or: [c++, c, c#, cuda, java, javascript, json, objective-c, proto, textproto]
args:
- -i
- -style=file
additional_dependencies: ['clang-format==22.1.5']
minimum_pre_commit_version: '2.9.2'各组件仓库.pre-commit-config.yaml示例
libmcpp(C/C++):
repos:
- repo: https://gitcode.com/openUBMC/pre-commit-hooks
rev: 0.1.2
hooks:
- id: conventional-commit
- id: add-signoff-and-change-id
- id: check-sr
- id: check-json
exclude: '\.vscode/'
- id: check-yaml
- id: clang-format
types_or: [c++, c]开发者测试
单元测试
pre-commit run clang-format --files src/foo.cpp
pre-commit run prettier --files src/bar.vue
pre-commit run stylua-format --files src/hardware.lua
pre-commit run luacheck --files src/hardware.lua集成测试
pre-commit run --all-files